'''此脚本负责读取原始数据并将其转化为使用数字等进行编号的更好处理的数据格式'''

# pandas
import pandas as pd

# numpy
import numpy as np

from collections import defaultdict
#下面一大截是读取

# 读取csv
def read_csv(filename):
    try:
        df = pd.read_csv(filename, encoding='utf-8')
    except UnicodeDecodeError:
        # 如果 utf-8 编码失败，尝试使用其他编码
        df = pd.read_csv(filename, encoding='ISO-8859-1')  # 或者使用 'latin1' 或 'gbk'
    return df


marker='$'
# 读取 距离时效信息表（df_matrix.csv）、订单需求量表（df_order.csv）、仓储数据表（df_proc.csv）
city2index_dict = {}  # 城市字典，维护城市到编号的映射
index2city_dict = {}  # 城市字典，维护编号到城市的映射
node2index_dict = {}  # 节点字典，维护节点到编号的映射
index2node_dict = {}  # 节点字典，维护编号到节点的映射

# 类型映射，约定0是港口CDC，1是内陆CDC节点，也就是CDC，2是第二层节点，也就是RDC，3是第三层节点，也就是门店
index2type_dict = {}  # 节点字典，维护节点到类型的映射

input_data_folder = 'input_data/'
output_data_folder = 'data_parser/'

# 先读取df_list.csv确定名字与索引
df_list=read_csv(input_data_folder+'df_list.csv')

# 初始化一个编号
index = 0

# 手动遍历每一行
for _, row in df_list.iterrows():
    location = row['Location']  # 获取Location列的值
    # 将Location与当前index的对应关系添加到列表中
    if location in city2index_dict:
        location += marker  # 给第二次出现的做一个标记
        
    city2index_dict[location] = index
    index2city_dict[index] = location

    index += 1  # 更新编号

index = 0
# 读取df_wh.csv得到第一、二层顶点信息
df_wh = read_csv(input_data_folder + 'df_wh.csv')

gangkou_flag = "gang-kou-CDC"
neilu_flag = "nei-lu-CDC"

for _, row in df_wh.iterrows():
    nodeName = row['Name']  # 获取Node列的值
    nodeType=0
    match (row['Type']):
        case 'CDC':
            if(nodeName==gangkou_flag):
                nodeType=0
            elif(nodeName==neilu_flag):
                nodeType=1
            else:
                nodeType=-1
        case 'RDC':
            nodeType=2
        case _:
            continue
    #给第二次出现的做一个标记
    if nodeName in node2index_dict:
        nodeName += marker
    node2index_dict[nodeName] = index
    index2node_dict[index] = nodeName
    index2type_dict[index] = nodeType
    index += 1

#读取df_customer.csv得到第三层顶点信息
df_wh = read_csv(input_data_folder + 'df_customer.csv')

for _, row in df_wh.iterrows():
    nodeName = row['Name']  # 获取Node列的值
    nodeType = 0
    match (row['Type']):
        case 'Customer':
            nodeType=3
        case _:
            continue
    # 给第二次出现的做一个标记
    if nodeName in node2index_dict:
        nodeName += marker
    node2index_dict[nodeName] = index
    index2node_dict[index] = nodeName
    index2type_dict[index] = nodeType
    index += 1

#读取订单信息df_order.csv
df_order = read_csv(input_data_folder + 'df_order.csv')

dm_qty={}#国内需求量
im_qty={}#国外需求量

dm_used_names=[]#记录重复出现的名字
im_used_names=[]#记录重复出现的名字

for _, row in df_order.iterrows():
    nodeName = row['Name']  # 获取Node列的值
    orderType=row['SKU']

    if(orderType=='dm'):
        if(nodeName in dm_used_names):
            nodeName += marker
        dm_used_names.append(nodeName)

        index=node2index_dict[nodeName]
        dm_qty[index]=row['qty']
    elif (orderType=='im'):
        if(nodeName in im_used_names):
            nodeName += marker
        im_used_names.append(nodeName)

        index=node2index_dict[nodeName]
        im_qty[index]=row['qty']

#读取仓库信息df_proc.csv
df_proc = read_csv(input_data_folder + 'df_proc.csv')

proc_names=[]#仓库名字
capacity_dict={}#仓库容量
processing_fee_dict={}#处理成本
opening_fee_dict={}#开仓成本


for _, row in df_proc.iterrows():
    nodeName = row['Name']  # 获取Node列的值
    if(nodeName in proc_names):
        nodeName += marker
    proc_names.append(nodeName)

    index=node2index_dict[nodeName]

    capacity_dict[index]=row['Capacity']
    processing_fee_dict[index]=row['Processing_fee']
    opening_fee_dict[index]=row['Opening_fee']

#读取距离信息df_matrix.csv
df_matrix = read_csv(input_data_folder + 'df_matrix.csv')


distance_dict = defaultdict(dict)
duration_dict = defaultdict(dict)

fromUsedNames=[]
fromUsedTos={}#记录每个边的终点是谁，避免重复计数
toUsedNames=[]
toUsedFroms={}#记录每个边的起点是谁，避免重复计数


for _, row in df_matrix.iterrows():
    fromNode=row['From']
    toNode=row['To']
    if(fromNode in fromUsedNames):
        fromNode += marker
    #这种出现过但是起点不同的说明指的是前一个，重新计算标记
    if(toNode in toUsedNames and toUsedFroms[toNode]==fromNode):
        toNode += marker

    #fromUsedNames.append(fromNode)
    toUsedNames.append(toNode)
    toUsedFroms[toNode]=fromNode

    fromIndex=node2index_dict[fromNode]
    toIndex=node2index_dict[toNode]
    distance_dict[fromIndex][toIndex]=row['Distance']
    duration_dict[fromIndex][toIndex]=row['Duration']

#全部读完了，开始写新的表
#共写三个表：opt_node.csv节点表，记录每个节点的信息
#opt_edge.csv边表，记录每条边的信息，包含用时、距离等
#opt_order.csv订单表，记录每个订单的信息

#先写节点表
node_table = {'Id': [], 'Type': [], 'Capacity': [], 'Processing_fee': [], 'Opening_fee': []}

#单位换算值
moneyScale=10000
for index in index2node_dict:
    node_table['Id'].append(index)
    node_table['Type'].append(index2type_dict[index])
    #剩下三个值有才写入没有则写入0 
    if (index in capacity_dict):
        node_table['Capacity'].append(capacity_dict[index])
    else:
        node_table['Capacity'].append(0)
    if (index in processing_fee_dict):
        node_table['Processing_fee'].append(processing_fee_dict[index]*moneyScale)
    else:
        node_table['Processing_fee'].append(0)
    if (index in opening_fee_dict):
        node_table['Opening_fee'].append(opening_fee_dict[index]*moneyScale)
    else:
        node_table['Opening_fee'].append(0)

opt_node = pd.DataFrame(node_table)

print("writing opt_node.csv...")
opt_node.to_csv(output_data_folder + 'opt_node.csv', index=False)

#再写边表
edge_table = {'From': [], 'To': [], 'Distance': [], 'Duration': []}

for fromIndex in distance_dict:
    for toIndex in distance_dict[fromIndex]:
        edge_table['From'].append(fromIndex)
        edge_table['To'].append(toIndex)
        edge_table['Distance'].append(distance_dict[fromIndex][toIndex])
        edge_table['Duration'].append(duration_dict[fromIndex][toIndex])

opt_edge = pd.DataFrame(edge_table)

print("writing opt_edge.csv...")
opt_edge.to_csv(output_data_folder + 'opt_edge.csv', index=False)

#最后写订单表
order_table={'Id':[],'im_qty':[],'dm_qty':[]}

for index in index2node_dict:
    if(index not in im_qty and index not in dm_qty):
        continue
    
    order_table['Id'].append(index)
    if(index in im_qty):
        order_table['im_qty'].append(im_qty[index])
    else:
        order_table['im_qty'].append(0)
    
    if(index in dm_qty):
        order_table['dm_qty'].append(dm_qty[index])
    else:
        order_table['dm_qty'].append(0)

opt_order = pd.DataFrame(order_table)

print("writing opt_order.csv...")
opt_order.to_csv(output_data_folder + 'opt_order.csv', index=False)

#最后输出一个表描述id和原本的名字之间的映射
id2name = {}
for name in index2node_dict:
    id2name[index2node_dict[name]]=name
id2name_table = {'Id': [], 'Name': []}

for index in id2name:
    id2name_table['Id'].append(index)
    id2name_table['Name'].append(id2name[index])

opt_id2name = pd.DataFrame(id2name_table)

print("writing opt_id2name.csv...")
opt_id2name.to_csv(output_data_folder + 'opt_id2name.csv', index=False)

print("Done!")